package innerclass;

/**
 * 匿名内部类
 */

public class AnonymousInnerClass {

    //创建外部类实例并调用方法
    public static void main(String[] args) {
        AnonymousOuter outer = new AnonymousOuter();
        outer.outFunction();
    }

}

//外部类
class AnonymousOuter {

    //私有属性
    private int num = 10;

    //方法
    public void outFunction(){

        //基于接口，实现一个匿名内部类
        //编译类型是InterFaceClass（接口类型），运行类型是匿名内部类，类名由程序自动分配生成（Outer$1）
        //是一种向上转型，动态绑定
        /*
          相当于：
          class Outer$1 implements InterFaceClass(){
              @override
              public void interFunction(){
                  system.out.println("调用基于接口的匿名内部列");
              }
          }
          InterFaceClass Impl = new Outer$1();
         */
        InterFaceClass Impl = new InterFaceClass() {
            @Override
            public void interFunction() {
                System.out.println("调用基于接口的匿名内部类");
            }
        };

        //调用匿名内部类中实现的接口方法
        Impl.interFunction();

        /*
            匿名内部类同时是一个对象，因此可以直接调用匿名内部类的方法
            new InterFaceClass() {
                @Override
                public void interFunction() {
                    System.out.println("调用基于接口的匿名内部类");
                }
            }.interFunction();

         */



        //基于继承父类，实现一个匿名内部类
        //编译类型是Base（父类类型），运行类型是匿名内部类，类名由程序自动分配生成（Outer$2）
        /*
          相当于：
          class Outer$2 extends Base{
              @Override
              public void baseFunction() {
                 System.out.println("调用基于子类的匿名内部类");
              }
          }
          Base sub = new Outer$2("sub");
         */
        //参数列表("sub")会传递给父类的构造器
        Base sub = new Base("sub") {
            @Override
            public void baseFunction() {
                System.out.println("调用基于子类的匿名内部类");
            }
        };

        //调用匿名内部类中重写的父类方法
        sub.baseFunction();
    }

}

//接口
interface InterFaceClass {

    //抽象方法
    public void interFunction();
}

//父类
class Base{
    private String name;

    //有参构造器
    public Base(String name) {
        this.name = name;
    }

    //方法
    public void baseFunction(){

    }
}